﻿#include "CLS_WgtBaseTreeWidget.h"
#include <QHeaderView>
#include <QStyleFactory>
#include <QCheckBox>
#include <QHBoxLayout>
#include "CLS_WgtItemToolBar.h"
#include <QEvent>
#include <QMouseEvent>
#include <QDebug>
#include <algorithm>
#include <QPushButton>
#include <QMimeData>
#include <QDrag>
#include <QApplication>
#include "CommonDef.h"

CLS_WgtBaseTreeWidget::CLS_WgtBaseTreeWidget(QWidget *_pParent, bool _blChecked, bool _blDrag, bool _blDrop, bool _blRightMenu, n_ItemBtnShowType _iBtnShowType)
    : QTreeWidget (_pParent)
    , m_blCheckEnable (_blChecked)
    , m_blDragEnable (_blDrag)
    , m_blDropEnable (_blDrop)
    , m_blRightMenuEnable(_blRightMenu)
    , m_iBtnShowType (_iBtnShowType)
{
    this->setMouseTracking(true);//追踪鼠标事件
    setRootIsDecorated(true);//小箭头
    setHeaderHidden(true);//隐藏表头
    setSelectionMode(QAbstractItemView::SingleSelection);//单行选中
    setSelectionBehavior(QAbstractItemView::SelectRows);// 设置行选中

    QHeaderView *pHeader = header();
    if (nullptr != pHeader)
    {
        //设置表头不显示
        pHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
        pHeader->setHidden(true);
    }

    //设置节点的勾选flag值
    if (m_blCheckEnable)
    {
        m_iItemFlag = m_iItemFlag | Qt::ItemIsUserCheckable;
    }
    else
    {
        m_iItemFlag = m_iItemFlag & ~Qt::ItemIsUserCheckable;
    }

    //设置节点的拖拽flag值
    if (m_blDragEnable)
    {
        m_iItemFlag = m_iItemFlag | Qt::ItemIsDragEnabled;
        setDragDropMode(QAbstractItemView::InternalMove);
        setDefaultDropAction(Qt::MoveAction);
        setDropIndicatorShown(false);
    }
    else
    {
        m_iItemFlag = m_iItemFlag & ~Qt::ItemIsDragEnabled;
    }

    if (m_blDropEnable)
    {
         m_iItemFlag = m_iItemFlag | Qt::ItemIsDropEnabled;
    }
    else
    {
         m_iItemFlag = m_iItemFlag & ~Qt::ItemIsDropEnabled;
    }

    //设置拖放
    setDragEnabled(m_blDragEnable);
    setAcceptDrops(m_blDropEnable);

    setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setAutoScroll(false);
    //设置列数为2，第一列放数据，第二列放自定义控件：toolbar
    setColumnCount(2);
    //节点单击
    connect(this, &QTreeWidget::itemClicked, this, &CLS_WgtBaseTreeWidget::SlotClicked);
    //节点双击
    connect(this, &QTreeWidget::itemDoubleClicked, this, &CLS_WgtBaseTreeWidget::SlotDblClicked);
    //节点选中
    connect(this, &QTreeWidget::currentItemChanged, this, &CLS_WgtBaseTreeWidget::SlotCurrentChanged);
	//折叠按钮被点击
	connect(this, &QTreeWidget::itemExpanded, this, &CLS_WgtBaseTreeWidget::SlotExpandedChanged);
}

CLS_WgtBaseTreeWidget::~CLS_WgtBaseTreeWidget()
{

}

void CLS_WgtBaseTreeWidget::SetLang(const QString &_qstrLang)
{
    Q_UNUSED(_qstrLang);
}

void CLS_WgtBaseTreeWidget::LoadStyleSheet(const QString &_qstrStyle)
{
    setStyleSheet(_qstrStyle);
}

int CLS_WgtBaseTreeWidget::Init(const QString &_qstrRootId, const QMap<QString, CLS_TreeItem> &_qmapTreeItems, bool _blRootNodeVisible)
{
    if (_qstrRootId.isEmpty() || !_qmapTreeItems.contains(_qstrRootId))
    {
        return -1;
    }

    m_qstrRootId = _qstrRootId;
    //清空数据和树控件
    Clear();
    //构建父子关系数据
    QMap<QString, QVector<CLS_TreeItem>> qmapChildren;
    QMap<QString, CLS_TreeItem>::const_iterator it = _qmapTreeItems.begin();
    for (; it != _qmapTreeItems.end(); ++it)
    {

        QString qstrParentId = it.value().m_qstrParentId;
        if (qstrParentId.isEmpty())
        {
            continue;
        }

        if (qmapChildren.contains(qstrParentId))
        {
            qmapChildren[qstrParentId].append(it.value());
        }
        else
        {
            QVector<CLS_TreeItem> vecItems;
            vecItems.append(it.value());
            qmapChildren[qstrParentId] = vecItems;
        }
    }

    //递归构建树
    return CreateTree(nullptr, _qmapTreeItems[_qstrRootId], qmapChildren, _blRootNodeVisible);
}

QTreeWidgetItem* CLS_WgtBaseTreeWidget::GetNodeById(const QString &_qstrId)
{
    QMap<QString, QTreeWidgetItem*>::const_iterator it = m_qmapItems.find(_qstrId);
    if (it == m_qmapItems.end())
    {
        return nullptr;
    }

    return it.value();
}

int CLS_WgtBaseTreeWidget::GetItemById(const QString &_qstrId, CLS_TreeItem &_clsItem)
{
    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return -1;
    }

    return GetBindData(pItem, _clsItem);
}

int CLS_WgtBaseTreeWidget::GetItemByName(const QString &_qstrName, QVector<CLS_TreeItem> &_qvecItems)
{
    if (!m_qmapItems.contains(m_qstrRootId))
    {
        return -1;
    }

    QVector<CLS_TreeItem> qvecChilds;
    int iRet = GetChilds(m_qstrRootId, qvecChilds, true);
    if (iRet < 0)
    {
        return iRet;
    }

    for (int i = 0; i < qvecChilds.size(); ++i)
    {
        //模糊比较该节点名称是否含有该查找关键字
        if (!qvecChilds.at(i).m_qstrName.contains(_qstrName, Qt::CaseInsensitive))
        {
            continue;
        }

        _qvecItems << qvecChilds[i];
    }

    return 0;
}

int CLS_WgtBaseTreeWidget::GetCurrentItem(CLS_TreeItem &_clsItem)
{
    QTreeWidgetItem* pItem = currentItem();
    if (nullptr == pItem || pItem->isDisabled())
    {
        return -1;
    }

    return GetBindData(pItem, _clsItem);
}

int CLS_WgtBaseTreeWidget::GetAllItems(QMap<QString, CLS_TreeItem> &_qmapTreeItems)
{
    QMap<QString, QTreeWidgetItem*>::const_iterator it = m_qmapItems.begin();
    for (; it != m_qmapItems.end(); ++it)
    {
        QTreeWidgetItem *pItem = it.value();
        if (nullptr == pItem)
        {
            continue;
        }

        CLS_TreeItem clsItem;
        int iRet = GetBindData(pItem, clsItem);
        if (iRet < 0)
        {
            continue;
        }

        _qmapTreeItems.insert(it.key(), clsItem);
    }
    return 0;
}

int CLS_WgtBaseTreeWidget::GetCheckedItems(QVector<CLS_TreeItem> &_qvecItems, bool _blOnlyLeafNode)
{
    if (!m_blCheckEnable)
    {
        return -1;
    }

    QMap<QString, QTreeWidgetItem*>::const_iterator it = m_qmapItems.begin();
    for (; it != m_qmapItems.end(); ++it)
    {
        QTreeWidgetItem *pItem = it.value();
        if (nullptr == pItem || pItem->isDisabled() || pItem->isHidden())
        {
            continue;
        }

        if (Qt::Unchecked == pItem->checkState(0) || Qt::PartiallyChecked == pItem->checkState(0))
        {
            continue;
        }

        CLS_TreeItem clsItem;
        int iRet = GetBindData(pItem, clsItem);
        if (iRet < 0)
        {
            continue;
        }

        //不管节点类型都存情况
        if (!_blOnlyLeafNode)
        {
            _qvecItems.push_back(clsItem);
            continue;
        }

        //只存叶子节点情况
        if (pItem->childCount() > 0)
        {
            continue;
        }
        //叶子节点
        _qvecItems.push_back(clsItem);
    }

    return 0;
}

int CLS_WgtBaseTreeWidget::GetCheckedNodes(QVector<CLS_TreeItem> &_qvecItems)
{
    //只要勾选的叶子节点
    return GetCheckedItems(_qvecItems, true);
}

bool CLS_WgtBaseTreeWidget::SortByNo(CLS_TreeItem &_item1, CLS_TreeItem &_item2)
{
    return _item1.m_iSort < _item2.m_iSort;
}

int CLS_WgtBaseTreeWidget::CreateTree(QTreeWidgetItem *_pParent, const CLS_TreeItem &_clsTreeItem, const QMap<QString, QVector<CLS_TreeItem>> &_qmapChildren, bool _blCreate)
{
    if (_clsTreeItem.m_qstrId.isEmpty())
    {
        return -1;
    }

    QTreeWidgetItem *pTreeItem = nullptr;
    if (_blCreate)
    {
        //创建节点
        pTreeItem = CreateNode(_clsTreeItem);
        if (nullptr == pTreeItem)
        {
            return -1;
        }

        if (nullptr == _pParent)
        {
            addTopLevelItem(pTreeItem); //根节点
        }
        else
        {
            _pParent->addChild(pTreeItem);
        }

        m_qmapItems.insert(_clsTreeItem.m_qstrId, pTreeItem);
        CLS_WgtItemToolBar *pToolBtn = CreateItemButtons(_clsTreeItem.m_qstrId, _clsTreeItem.m_qvecItemButtons);
        if (nullptr != pToolBtn)
        {
            //设置一个QStackedWidget，第一层放置空控件，第二层放置toolbar，为解决树控件折叠和展开时自动显示item的自定义控件问题
            CLS_WgtToolBtnStack *pStackWgt = new CLS_WgtToolBtnStack;
            QWidget *pEmptyWgt = new QWidget;
            pStackWgt->addWidget(pEmptyWgt);
            pStackWgt->addWidget(pToolBtn);
            setItemWidget(pTreeItem, 1, pStackWgt);
            if (n_ItemBtnShowType_AlwaysShow != m_iBtnShowType)
            {
                  pStackWgt->setCurrentIndex(0);
            }
        }
    }

    QVector<CLS_TreeItem> vecNodes = _qmapChildren[_clsTreeItem.m_qstrId];//子结点列表
    //排序
    std::sort(vecNodes.begin(), vecNodes.end(), SortByNo);
    for (int i = 0; i < vecNodes.size(); ++i)
    {
        CreateTree(pTreeItem, vecNodes.at(i), _qmapChildren);
    }

    return 0;
}

QTreeWidgetItem *CLS_WgtBaseTreeWidget::CreateNode(const CLS_TreeItem &_clsItem)
{
	QApplication::processEvents();
    if (_clsItem.m_qstrId.isEmpty())
    {
        return nullptr;
    }

    CLS_WgtTreeWidgetItem *pItem = new CLS_WgtTreeWidgetItem(n_TreeItemUserType_User);
    if(nullptr == pItem)
    {
        return nullptr;
    }

    connect(pItem, &CLS_WgtTreeWidgetItem::SignCheckStateChanged, this, &CLS_WgtBaseTreeWidget::SlotCheckStateChanged);

    if (Qt::NoItemFlags == _clsItem.m_iItemFlag)
    {
        //如果用户没有设置节点标志，则程序按传入的相关参数赋予默认节点标志
        pItem->setFlags(m_iItemFlag);
    }
    else
    {
        //如果用户设置了节点标志，按用户设定的节点标志设定树节点flag值
        pItem->setFlags(_clsItem.m_iItemFlag);
    }

    if (m_blCheckEnable)
    {
        pItem->setCheckState(0, Qt::Unchecked);
    }   

    QString qstrTextName = _clsItem.m_qstrName;
    if (m_iMaxLength > 0)
    {
        QFontMetrics font(pItem->font(0));
        qstrTextName = font.elidedText(qstrTextName, Qt::ElideRight, m_iMaxLength);
    }

    pItem->setText(0, qstrTextName);
    pItem->setToolTip(0, _clsItem.m_qstrToolTip);
    pItem->setIcon(0, QIcon(_clsItem.m_qstrIcon));
    QVariant qvaData;
    qvaData.setValue(_clsItem);
    pItem->setData(0, Qt::UserRole, _clsItem.m_qstrId);
    pItem->setData(0, Qt::UserRole+1, qvaData);
    return pItem;
}

void CLS_WgtBaseTreeWidget::Clear()
{
    clear();//清控件
    m_qmapItems.clear();//清数据
    m_pLastItem = nullptr;
}

void CLS_WgtBaseTreeWidget::SetItemExpandStatus(const QString &_qstrId, n_TreeExpandType _iExpandType)
{
    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    if (n_TreeExpandType_Hide == _iExpandType)
    {
        //折叠
        collapseItem(pItem);
    }
    else if (n_TreeExpandType_Current == _iExpandType)
    {
        //展开当前节点
        QVector<QTreeWidgetItem*> vecParentNodes;
        GetParentNode(pItem, vecParentNodes);
        for (int i = 0; i < vecParentNodes.size(); ++i)
        {
            QTreeWidgetItem* pItem = vecParentNodes.at(i);
            if (nullptr == pItem)
            {
                continue;
            }

            this->expandItem(pItem);
        }

        this->expandItem(pItem);
    }
    else if (n_TreeExpandType_All == _iExpandType)
    {
        //展开当前节点和全部子节点
        QVector<QTreeWidgetItem*> vecParentNodes;
        GetParentNode(pItem, vecParentNodes);
        for (int i = 0; i < vecParentNodes.size(); ++i)
        {
            QTreeWidgetItem* pItem = vecParentNodes.at(i);
            if (nullptr == pItem)
            {
                continue;
            }

            this->expandItem(pItem);
        }

        this->expandItem(pItem);
        //子节点处理
        QVector<QTreeWidgetItem*> vecChildNodes;
        GetChildNode(pItem, vecChildNodes, true);
        for (int i = 0; i < vecChildNodes.size(); ++i)
        {
            QTreeWidgetItem* pItem = vecChildNodes.at(i);
            if (nullptr == pItem)
            {
                continue;
            }

            this->expandItem(pItem);
        }
    }
    else
    {}
}

void CLS_WgtBaseTreeWidget::SetAllExpandStatus(bool _blShow)
{
    if (_blShow)
    {
        expandAll();
    }
    else
    {
        collapseAll();
    }
}

void CLS_WgtBaseTreeWidget::SetShowItemByName(const QString &_qstrName)
{
    if (_qstrName.isEmpty())
    {
        return;
    }

    QMap<QString, QTreeWidgetItem*> qmapItems;
    GetNodeByName(_qstrName, qmapItems);
    QList<QString> qlistId = qmapItems.keys(); //满足条件的id列表
    for (QMap<QString, QTreeWidgetItem*>::const_iterator it = qmapItems.begin(); it != qmapItems.end(); ++it)
    {
        QTreeWidgetItem* pCurItem = it.value();
        QMap<QString, QTreeWidgetItem*> qmapParentItems;
        GetParentNode(pCurItem, qmapParentItems);
        qlistId << qmapParentItems.keys();
    }

    //显示搜索结果树
    for (QMap<QString, QTreeWidgetItem*>::const_iterator it = m_qmapItems.begin(); it != m_qmapItems.end(); ++it)
    {
        QTreeWidgetItem* pItem = it.value();
        if (nullptr == pItem)
        {
            continue;
        }

        QString qstrId = it.key();
        if (!qlistId.contains(qstrId))
        {
            pItem->setHidden(true);
        }
        else
        {
            //显示并展开组织结构
            pItem->setHidden(false);
            pItem->setExpanded(true);
        }
    }
}

int CLS_WgtBaseTreeWidget::GetChildNode(QTreeWidgetItem* _pItem, QVector<QTreeWidgetItem*> &_vecChildNodes, bool _blRecursive)
{
    if (nullptr == _pItem)
    {
        return -1;
    }

    int iChildCounts = _pItem->childCount();
    for (int i = 0; i < iChildCounts; ++i)
    {
        QTreeWidgetItem* pItem = _pItem->child(i);
        if (nullptr == pItem)
        {
            continue;
        }

        _vecChildNodes.push_back(pItem);
        if (!_blRecursive)
        {
            continue;
        }

        GetChildNode(_pItem->child(i), _vecChildNodes, _blRecursive);
    }

    return 0;
}

int CLS_WgtBaseTreeWidget::GetParentNode(QTreeWidgetItem* _pItem, QVector<QTreeWidgetItem*> &_vecParentNodes)
{
    if (nullptr == _pItem)
    {
        return -1;
    }

    QTreeWidgetItem* pParentItem = _pItem->parent();
    if (nullptr == pParentItem)
    {
        return -1;
    }

    _vecParentNodes.push_back(pParentItem);
    GetParentNode(pParentItem, _vecParentNodes);
    return 0;
}

int CLS_WgtBaseTreeWidget::GetParentNode(QTreeWidgetItem* _pItem, QMap<QString, QTreeWidgetItem*> &_qmapParentNodes)
{
    if (nullptr == _pItem)
    {
        return -1;
    }

    QTreeWidgetItem* pParentItem = _pItem->parent();
    if (nullptr == pParentItem)
    {
        return -1;
    }

    CLS_TreeItem clsItem;
    int iRet = GetBindData(pParentItem, clsItem);
    if (iRet < 0)
    {
        return iRet;
    }

    //递归查找该节点的组织结构
    _qmapParentNodes.insert(clsItem.m_qstrId, pParentItem);
    GetParentNode(pParentItem, _qmapParentNodes);
    return 0;
}

int CLS_WgtBaseTreeWidget::GetNodeByName(const QString &_qstrName, QMap<QString, QTreeWidgetItem*> &_qmapItems)
{
    if (_qstrName.isEmpty())
    {
        return -1;
    }

    for (QMap<QString, QTreeWidgetItem*>::const_iterator it = m_qmapItems.begin(); it != m_qmapItems.end(); ++it)
    {
        QTreeWidgetItem* pItem = it.value();
        if (nullptr == pItem)
        {
            continue;
        }

        CLS_TreeItem clsItem;
        int iRet = GetBindData(pItem, clsItem);
        if (iRet < 0)
        {
            continue;
        }
        //模糊比较该节点名称是否含有该查找关键字
        if (!clsItem.m_qstrName.contains(_qstrName, Qt::CaseInsensitive))
        {
            continue;
        }

        _qmapItems.insert(clsItem.m_qstrId, pItem);
    }

    return 0;
}

CLS_WgtItemToolBar *CLS_WgtBaseTreeWidget::CreateItemButtons(const QString &_qstrId, const QVector<CLS_ItemButton> &_vecItemButtons)
{
    if (_vecItemButtons.isEmpty())
    {
        return nullptr;
    }

    //构建toolbar
    CLS_WgtItemToolBar *pWgtToolBtn = new CLS_WgtItemToolBar;
    pWgtToolBtn->Init(_vecItemButtons, _qstrId);
    connect(pWgtToolBtn, &CLS_WgtItemToolBar::SignTriggered, this, &CLS_WgtBaseTreeWidget::SignClickButton);
    return pWgtToolBtn;
}

void CLS_WgtBaseTreeWidget::mousePressEvent(QMouseEvent *_pEvent)
{
    if (nullptr == _pEvent)
    {
        return;
    }

    QTreeWidgetItem *pItem = itemAt(_pEvent->pos());
    if (nullptr == pItem)
    {
        return QTreeWidget::mousePressEvent(_pEvent);
    }

    if (Qt::LeftButton == _pEvent->button() && m_blDragEnable)
    {
        //只叶子节点支持拖拽
        QTreeWidgetItem *pCurItem = currentItem();
        if (nullptr == pCurItem || pCurItem->childCount() > 0)
        {
            return QTreeWidget::mousePressEvent(_pEvent);
        }

        GetBindData(pCurItem, m_clsDragBeginItem);
        return QTreeWidget::mousePressEvent(_pEvent);
    }
    else if (Qt::RightButton == _pEvent->button() && m_blRightMenuEnable)
    {
        QTreeWidgetItem *pItem = itemAt(_pEvent->pos());
        if (nullptr == pItem)
        {
            //非节点右键
            return QTreeWidget::mousePressEvent(_pEvent);
        }

        CLS_TreeItem clsData;
        int iRet = GetBindData(pItem, clsData);
        if (iRet < 0)
        {
            return QTreeWidget::mousePressEvent(_pEvent);
        }

        SetCurrentItem(clsData.m_qstrId, true);
        emit SignRightClicked(clsData.m_qstrId, clsData);
    }
    else
    {}

    QTreeWidget::mousePressEvent(_pEvent);
}

void CLS_WgtBaseTreeWidget::leaveEvent(QEvent *_pEvent)
{
    if (nullptr != m_pLastItem)
    {
        QWidget *pWidget = itemWidget(m_pLastItem, 1);
        if (nullptr != pWidget)
        {
            QStackedWidget *pStackedWgt = dynamic_cast<QStackedWidget *>(pWidget);
            if (nullptr != pStackedWgt && pStackedWgt->count() >= 2)
            {
                pStackedWgt->setCurrentIndex(0);
            }
        }
    }

    return QTreeWidget::leaveEvent(_pEvent);
}

void CLS_WgtBaseTreeWidget::mouseMoveEvent(QMouseEvent *_pEvent)
{
    if (nullptr == _pEvent)
    {
        return;
    }

    if (m_blDragEnable && m_blDraging)
    {//处理拖拽
        return QTreeWidget::mouseMoveEvent(_pEvent);
    }

    //目前只处理鼠标滑过的Toolbar上的菜单按钮状态
    if (n_ItemBtnShowType_EnterShow != m_iBtnShowType)
    {
        return QTreeWidget::mouseMoveEvent(_pEvent);
    }

    QTreeWidgetItem *pItem = itemAt(_pEvent->pos());
    //过滤：处理的是相同节点
    if (m_pLastItem == pItem)
    {
        return QTreeWidget::mouseMoveEvent(_pEvent);
    }

    //处理上一节点
    if (nullptr != m_pLastItem)
    {
        QWidget *pWidget = itemWidget(m_pLastItem, 1);
        if (nullptr != pWidget)
        {
            QStackedWidget *pStackedWgt = dynamic_cast<QStackedWidget *>(pWidget);
            if (nullptr != pStackedWgt && pStackedWgt->count() >= 2)
            {
                pStackedWgt->setCurrentIndex(0);
            }
        }
    }

    m_pLastItem = pItem;
    if (nullptr == pItem)
    {
        return QTreeWidget::mouseMoveEvent(_pEvent);
    }

    //处理当前节点
    QWidget *pWidget = itemWidget(pItem, 1);
    if (nullptr != pWidget)
    {
        QStackedWidget *pStackedWgt = dynamic_cast<QStackedWidget *>(pWidget);
        if (nullptr != pStackedWgt && pStackedWgt->count() >= 2)
        {
            pStackedWgt->setCurrentIndex(1);
        }
    }

    QTreeWidget::mouseMoveEvent(_pEvent);
}

int CLS_WgtBaseTreeWidget::GetBindData(QTreeWidgetItem* _pItem, CLS_TreeItem &_clsItem)
{
    if (nullptr == _pItem)
    {
        return -1;
    }

    QVariant itemData = _pItem->data(0, Qt::UserRole+1);
    //数据非法或者转换不成功返回错误
    if (!itemData.isValid() || !itemData.canConvert<CLS_TreeItem>())
    {
        return -1;
    }

    _clsItem = itemData.value<CLS_TreeItem>();
return 0;
}

void CLS_WgtBaseTreeWidget::AddItem(const CLS_TreeItem &_clsTreeItem)
{
	QTreeWidgetItem* pNode = GetNodeById(_clsTreeItem.m_qstrId);
	if (nullptr != pNode)
	{
		return;
	}

	//找父节点
	QString qstrParentId = _clsTreeItem.m_qstrParentId;
	QTreeWidgetItem* pParentNode = GetNodeById(qstrParentId);
	if (nullptr == pParentNode)
	{
		//父节点为空，说明是根节点，退出
		return;
	}
	else
	{
		QApplication::processEvents();
		QTreeWidgetItem *pTreeItem = CreateNode(_clsTreeItem);
		if (nullptr == pTreeItem)
		{
			return;
		}

		m_qmapItems.insert(_clsTreeItem.m_qstrId, pTreeItem);

		//找到该父节点下挂的所有子节点
		int iChildCount = pParentNode->childCount();
		if (iChildCount <= 0)
		{
			pParentNode->insertChild(0, pTreeItem);
		}

		int iFindIndex = -1;
		for (int i = 0; i < iChildCount; ++i)
		{
			QTreeWidgetItem *pChildNode = pParentNode->child(i);
			if (nullptr == pChildNode)
			{
				continue;
			}

			CLS_TreeItem clsItem;
			int iRet = GetBindData(pChildNode, clsItem);
			if (iRet < 0)
			{
				continue;
			}

			if (clsItem.m_iSort > _clsTreeItem.m_iSort)
			{
				iFindIndex = i;
				break;
			}
		}

		if (iFindIndex < 0)
		{
			//在末尾位置插入
			pParentNode->insertChild(iChildCount, pTreeItem);
		}
		else
		{
			//在合适位置插入
			pParentNode->insertChild(iFindIndex, pTreeItem);
		}

		CLS_WgtItemToolBar *pToolBtn = CreateItemButtons(_clsTreeItem.m_qstrId, _clsTreeItem.m_qvecItemButtons);
		if (nullptr != pToolBtn)
		{
			//设置一个QStackedWidget，第一层放置空控件，第二层放置toolbar，为解决树控件折叠和展开时自动显示item的自定义控件问题
			CLS_WgtToolBtnStack *pStackWgt = new CLS_WgtToolBtnStack;
			QWidget *pEmptyWgt = new QWidget;
			pStackWgt->addWidget(pEmptyWgt);
			pStackWgt->addWidget(pToolBtn);
			pStackWgt->setGeometry(0, 0, 50, 30);
			setItemWidget(pTreeItem, 1, pStackWgt);
			if (n_ItemBtnShowType_AlwaysShow != m_iBtnShowType)
			{
				pStackWgt->setCurrentIndex(0);
			}
		}

	}
}

void CLS_WgtBaseTreeWidget::AddItems(const QVector<CLS_TreeItem> &_qvecTreeItems)
{
	for (int i = 0; i < _qvecTreeItems.size(); ++i)
	{
		AddItem(_qvecTreeItems.at(i));
	}
}

void CLS_WgtBaseTreeWidget::AddItems(const QString &_qstrParentId, const QVector<CLS_TreeItem> &_qvecTreeItems)
{
	if (_qstrParentId.isEmpty() || _qvecTreeItems.isEmpty())
	{
		return;
	}

	QTreeWidgetItem* pParentNode = GetNodeById(_qstrParentId);
	if (nullptr == pParentNode)
	{
		//父节点为空，说明是根节点，退出
		return;
	}

	CommonFunc::RunTimeLog *pLog = new CommonFunc::RunTimeLog(QString("[AddItems: CreateNode"));

	QList<QTreeWidgetItem *> qlistAddItems;

	if (_qvecTreeItems.size() >= 30)
	{
		int iRemainder = _qvecTreeItems.size() % 4;
		int iPerNums = _qvecTreeItems.size() / 4;
		QVector<bool> qvecTasks;
		for (int i = 0; i < 4; ++i)
		{
			//QVector<CLS_TreeItem> qvecTreeItems = _qvecTreeItems.
			std::thread th([&, _qvecTreeItems, i]() {
				int iBegin = i * iPerNums;
				int iEnd = 0;
				if (i == 4 && iRemainder > 0)
				{
					iEnd = _qvecTreeItems.size();
				}
				else
				{
					iEnd = (i + 1) * iPerNums;
				}

				for (int j = iBegin; j < iEnd; ++j)
				{
					QApplication::processEvents();
					QTreeWidgetItem *pTreeItem = CreateNode(_qvecTreeItems.at(j));
					if (nullptr == pTreeItem)
					{
						continue;
					}
					m_qmapItems.insert(_qvecTreeItems.at(j).m_qstrId, pTreeItem);
					qlistAddItems << pTreeItem;
				}

				qvecTasks << i;
			});

			th.detach();
		}

		std::thread th([&]() {
			while (1)
			{
				if (qvecTasks.size() == 4)
				{
					break;
				}

				std::this_thread::sleep_for(std::chrono::milliseconds(100));
			}

		});
		th.join();

	}
	else
	{
		for (auto &item : _qvecTreeItems)
		{
			QApplication::processEvents();
			QTreeWidgetItem *pTreeItem = CreateNode(item);
			if (nullptr == pTreeItem)
			{
				continue;
			}
			m_qmapItems.insert(item.m_qstrId, pTreeItem);
			qlistAddItems << pTreeItem;
		}
	}

	delete pLog;
	qDebug() << "[AddItems: qlistAddItems.size]" << qlistAddItems.size();
	pLog = new CommonFunc::RunTimeLog(QString("[AddItems: addChildren"));

	QApplication::processEvents();
	pParentNode->addChildren(qlistAddItems);
	QApplication::processEvents();

	delete pLog;
}

void CLS_WgtBaseTreeWidget::DeleteItem(const QString &_qstrId)
{
    if (_qstrId.isEmpty())
    {
        return;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    //缓存处理
    m_qmapItems.remove(_qstrId);
    QVector<QTreeWidgetItem*> vecChildNodes;
    GetChildNode(pItem, vecChildNodes, true);
    for (int i = 0; i < vecChildNodes.size(); ++i)
    {
        QTreeWidgetItem* pNode = vecChildNodes.at(i);
        if (nullptr == pNode)
        {
            continue;
        }

        CLS_TreeItem clsItem;
        int iRet = GetBindData(pNode, clsItem);
        if (iRet < 0)
        {
            continue;
        }

        QString qstrId = clsItem.m_qstrId;
        m_qmapItems.remove(qstrId);
    }

    //界面树控件处理
    QTreeWidgetItem *pParentItem = pItem->parent();
    if (nullptr == pParentItem)
    {
        //删顶层节点
        int iTopCount = topLevelItemCount();
        int iTopIndex = -1;
        for (int i = 0; i < iTopCount; ++i)
        {
            QTreeWidgetItem *pNode = topLevelItem(i);
            if (pNode == pItem)
            {
                iTopIndex  = i;
                break;
            }
        }

        if (iTopIndex >= 0)
        {
            takeTopLevelItem(iTopIndex);
        }
    }
    else
    {
        //删非顶层节点
        pParentItem->removeChild(pItem);
    }
}

void CLS_WgtBaseTreeWidget::UpdateItem(const CLS_TreeItem &_clsItem)
{
    QTreeWidgetItem* pItem = GetNodeById(_clsItem.m_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    if (Qt::NoItemFlags == _clsItem.m_iItemFlag)
    {
        //如果用户没有设置节点标志，则程序按传入的相关参数赋予默认节点标志
        pItem->setFlags(m_iItemFlag);
    }
    else
    {
        //如果用户设置了节点标志，按用户设定的节点标志设定树节点flag值
        pItem->setFlags(_clsItem.m_iItemFlag);
    }

    QString qstrTextName = _clsItem.m_qstrName;
    if (m_iMaxLength > 0)
    {
        QFontMetrics font(pItem->font(0));
        qstrTextName = font.elidedText(qstrTextName, Qt::ElideRight, m_iMaxLength);
    }

    pItem->setText(0, qstrTextName);
    pItem->setToolTip(0, _clsItem.m_qstrToolTip);
    pItem->setIcon(0, QIcon(_clsItem.m_qstrIcon));
    QVariant qvaData;
    qvaData.setValue(_clsItem);
    pItem->setData(0, Qt::UserRole, _clsItem.m_qstrId);
    pItem->setData(0, Qt::UserRole+1, qvaData);
}

void CLS_WgtBaseTreeWidget::UpdateItemIcon(const QString &_qstrId, const QString &_qstrIcon)
{
    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    pItem->setIcon(0, QIcon(_qstrIcon));
}

void CLS_WgtBaseTreeWidget::SetCurrentItem(const QString _qstrId, bool _blSend)
{
    if (_qstrId.isEmpty())
    {
        return;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    if (!_blSend)
    {
        m_blCustomSelected = false;
    }

    scrollToItem(pItem);
    setCurrentItem(pItem);
    m_blCustomSelected = true;
}

void CLS_WgtBaseTreeWidget::SetItemCheckStatus(const QString &_qstrId, Qt::CheckState _iState, bool _blSend)
{
    if (_qstrId.isEmpty() || !m_blCheckEnable)
    {
        return;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    if (!_blSend)
    {
        m_blCustomChecked = false;
    }

    pItem->setCheckState(0, _iState);
    m_blCustomChecked = true;
}

void CLS_WgtBaseTreeWidget::SetShowItemById(const QString &_qstrId)
{
    if (_qstrId.isEmpty())
    {
        return;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return;
    }

    //找到该节点的组织结构上的根节点，展开
    QMap<QString, QTreeWidgetItem*> qmapParentItems;
    GetParentNode(pItem, qmapParentItems);
    QList<QString> qlistId = qmapParentItems.keys();
    qlistId.append(_qstrId);
    //显示搜索结果树
    for (QMap<QString, QTreeWidgetItem*>::iterator it = m_qmapItems.begin(); it != m_qmapItems.end(); ++it)
    {
        QTreeWidgetItem* pItem = it.value();
        if (nullptr == pItem)
        {
            continue;
        }

        QString qstrId = it.key();
        if (!qlistId.contains(qstrId))
        {
            pItem->setHidden(true);
        }
        else
        {
            //显示并展开组织结构
            pItem->setHidden(false);
            pItem->setExpanded(true);
        }
    }
}

void CLS_WgtBaseTreeWidget::SlotClickButton(QString _qstrId, CLS_ItemButton _clsBtn)
{
    //将Toolbar中被点击的按钮信息发送出去
    emit SignClickButton(_qstrId, _clsBtn);
}

void CLS_WgtBaseTreeWidget::SlotClicked(QTreeWidgetItem *_pItem, int _iColumn)
{
    Q_UNUSED(_iColumn)
    if (nullptr == _pItem)
    {
        return;
    }

    CLS_TreeItem clsItem;
    int iRet = GetBindData(_pItem, clsItem);
    if (iRet < 0)
    {
        return;
    }

    emit SignClicked(clsItem.m_qstrId, clsItem);
}

void CLS_WgtBaseTreeWidget::SlotDblClicked(QTreeWidgetItem *_pItem, int _iColumn)
{
    Q_UNUSED(_iColumn)
    if (nullptr == _pItem)
    {
        return;
    }

    CLS_TreeItem clsItem;
    int iRet = GetBindData(_pItem, clsItem);
    if (iRet < 0)
    {
        return;
    }

    emit SignDblClicked(clsItem.m_qstrId, clsItem);
}

void CLS_WgtBaseTreeWidget::SlotCheckStateChanged(QTreeWidgetItem *_pItem, bool _blChecked)
{
    //处理节点勾选
    if (!m_blCheckEnable || nullptr == _pItem || !m_blCustomChecked)
    {
        return;
    }

    CLS_TreeItem clsItem;
    int iRet = GetBindData(_pItem, clsItem);
    if (iRet < 0)
    {
        return;
    }

    emit SignCheckedStatusChanged(clsItem.m_qstrId, _blChecked, clsItem);
}

void CLS_WgtBaseTreeWidget::SlotCurrentChanged(QTreeWidgetItem *_pCurrent, QTreeWidgetItem *_pPrevious)
{
    //非用户选中
    if (!m_blCustomSelected)
    {
        return;
    }

    //获得当前选中态节点信息
    if (nullptr == _pCurrent)
    {
        return;
    }

    CLS_TreeItem clsItem;
    int iRet = GetBindData(_pCurrent, clsItem);
    if (iRet < 0)
    {
        return;
    }

    //获得之前选中态节点信息
    QString qstrOldId = "";
    if (nullptr != _pPrevious)
    {
        CLS_TreeItem clsPreItem;
        int iRet = GetBindData(_pPrevious, clsPreItem);
        if (iRet >= 0)
        {
            qstrOldId = clsPreItem.m_qstrId;
        }
    }
	
    emit SignSelected(clsItem.m_qstrId, clsItem, qstrOldId);
}

void CLS_WgtBaseTreeWidget::SlotExpandedChanged(QTreeWidgetItem *_pCurrent)
{
	//获得当前选中态节点信息
	if (nullptr == _pCurrent)
	{
		return;
	}

	CLS_TreeItem clsItem;
	int iRet = GetBindData(_pCurrent, clsItem);
	if (iRet < 0)
	{
		return;
	}

	emit SignExpanded(clsItem.m_qstrId, clsItem);
}

void CLS_WgtBaseTreeWidget::dragEnterEvent(QDragEnterEvent *_pEvent)
{
    if (nullptr == _pEvent)
    {
        return;
    }

    if (!m_blDragEnable)
    {
        return QTreeWidget::dragEnterEvent(_pEvent);
    }

    //接受拖拽
    _pEvent->setDropAction(Qt::MoveAction);
    _pEvent->accept();
    m_blDraging = true;
    QTreeWidget::dragEnterEvent(_pEvent);
}

void CLS_WgtBaseTreeWidget::dropEvent(QDropEvent *_pEvent)
{
    if (nullptr == _pEvent)
    {
        return;
    }

    if (!m_blDragEnable)
    {
        return QTreeWidget::dropEvent(_pEvent);
    }

    QTreeWidgetItem *pDropItem = itemAt(_pEvent->pos());
    if (nullptr == pDropItem || pDropItem->isDisabled())
    {
        _pEvent->setDropAction(Qt::IgnoreAction);
        _pEvent->ignore();
        return QTreeWidget::dropEvent(_pEvent);
    }

    CLS_TreeItem dropItem;
    GetBindData(pDropItem, dropItem);
    if (dropItem.m_qstrId == m_clsDragBeginItem.m_qstrId)
    {
        _pEvent->setDropAction(Qt::IgnoreAction);
        _pEvent->ignore();
        return QTreeWidget::dropEvent(_pEvent);
    }

    emit SignDroped(m_clsDragBeginItem, dropItem);
    m_blDraging = false;
    QTreeWidget::dropEvent(_pEvent);
}

void CLS_WgtBaseTreeWidget::startDrag(Qt::DropActions _qActionList)
{
    Q_UNUSED(_qActionList);
    QTreeWidgetItem *pItem = currentItem();
    if (nullptr == pItem || pItem->isDisabled())
    {
        return;
    }

    QString qstrItemRef = QString::number(qulonglong(pItem));
    QByteArray qbyteItemData;
    qbyteItemData = QVariant(qstrItemRef).toByteArray();

    QMimeData *pMimeData = new QMimeData;
    pMimeData->setData("application/x-qabstractitemmodeldatalist", qbyteItemData);

    QPushButton *pDragBgBtn = new QPushButton();
    pDragBgBtn->setObjectName("dragBgBtn");
    QIcon icon = pItem->icon(0);
    pDragBgBtn->setIcon(icon);
    pDragBgBtn->setText(pItem->text(0));

    QPixmap pix;
    pix = pix.grabWidget(pDragBgBtn);

    QDrag *pDrag = new QDrag(this);
    pDrag->setMimeData(pMimeData);
    pDrag->setPixmap(pix);
    pDrag->setHotSpot(QPoint(0,0));
    pDrag->exec(Qt::MoveAction);
}

int CLS_WgtBaseTreeWidget::GetChilds(const QString &_qstrId, QVector<CLS_TreeItem> &_qvecChilds, bool _blRecursive)
{
    if (_qstrId.isEmpty())
    {
        return -1;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return -1;
    }

    QVector<QTreeWidgetItem*> vecChildNodes;
    int iRet = GetChildNode(pItem, vecChildNodes, _blRecursive);
    if (iRet < 0)
    {
        return iRet;
    }

    for (int i = 0; i < vecChildNodes.size(); ++i)
    {
        QTreeWidgetItem* pNode = vecChildNodes.at(i);
        if (nullptr == pNode)
        {
            continue;
        }

        CLS_TreeItem clsItem;
        int iRet = GetBindData(pNode, clsItem);
        if (iRet < 0)
        {
            continue;
        }

        _qvecChilds.push_back(clsItem);
    }

    return 0;
}

int CLS_WgtBaseTreeWidget::GetParent(const QString &_qstrId, CLS_TreeItem &_parentItem)
{
    if (_qstrId.isEmpty())
    {
        return -1;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return -1;
    }

    QTreeWidgetItem *pParentItem = pItem->parent();
    if (nullptr == pParentItem)
    {
        return -1;
    }

    CLS_TreeItem clsItem;
    int iRet = GetBindData(pParentItem, _parentItem);
    if (iRet < 0)
    {
        return iRet;
    }

    return 0;
}

int CLS_WgtBaseTreeWidget::GetItemCheckStatus(const QString &_qstrId, Qt::CheckState &_iState)
{
    if (_qstrId.isEmpty())
    {
        return -1;
    }

    QTreeWidgetItem* pItem = GetNodeById(_qstrId);
    if (nullptr == pItem)
    {
        return -1;
    }

    _iState = pItem->checkState(0);
    return 0;
}

void CLS_WgtBaseTreeWidget::SetTextMaxWidth(int _iMaxLength)
{
    m_iMaxLength = _iMaxLength;
}

void CLS_WgtBaseTreeWidget::mouseReleaseEvent(QMouseEvent *_pEvent)
{
    m_blDraging = false;
    QTreeWidget::mouseReleaseEvent(_pEvent);
}


int CLS_WgtBaseTreeWidget::MoveUpOneRow(const QString &_qstrSrcId, const QString &_qstrDesId)
{
    //获得源和被交换节点的绑定数据
    QTreeWidgetItem* pSrcItem = GetNodeById(_qstrSrcId);
    if (nullptr == pSrcItem)
    {
        return -1;
    }

    CLS_TreeItem srcData;
    GetBindData(pSrcItem, srcData);

    QTreeWidgetItem* pDesItem = GetNodeById(_qstrDesId);
    if (nullptr == pDesItem)
    {
        return -1;
    }

    CLS_TreeItem desData;
    GetBindData(pDesItem, desData);

    QTreeWidgetItem *pSrcParent = pSrcItem->parent();
    if (nullptr == pSrcParent)
    {
        return -1;
    }

    int iChildCount = pSrcParent ->childCount();
    //原下标位置,如果是第0个元素，不能再上移
    int iSrcIndex = pSrcParent->indexOfChild(pSrcItem);
    if (iSrcIndex <= 0 || iSrcIndex >= iChildCount)
    {
        return -1;
    }

    int iDesIndex = pSrcParent->indexOfChild(pDesItem);
    if (iDesIndex < 0 || iDesIndex >= iChildCount)
    {
        return -1;
    }

    //改绑定
    int iExchangeTemp = srcData.m_iSort;
    srcData.m_iSort = desData.m_iSort;
    desData.m_iSort = iExchangeTemp;

    QVariant qvaSrcData;
    qvaSrcData.setValue(srcData);
    pSrcItem->setData(0, Qt::UserRole+1, qvaSrcData);

    QVariant qvaDesData;
    qvaDesData.setValue(desData);
    pDesItem->setData(0, Qt::UserRole+1, qvaDesData);

    //改界面
    QList<QTreeWidgetItem*> qlistChilds;
    for (int i = 0; i < iChildCount; ++i)
    {
        qlistChilds << pSrcParent->child(i);
    }

    pSrcParent->takeChildren();
    qlistChilds[iSrcIndex] = qlistChilds[iDesIndex];
    qlistChilds[iDesIndex] = pSrcItem;
    pSrcParent->addChildren(qlistChilds);
    scrollToItem(pSrcItem);
    setCurrentItem(pSrcItem);
    return 0;
}

int CLS_WgtBaseTreeWidget::MoveDownOneRow(const QString &_qstrSrcId, const QString &_qstrDesId)
{
    //获得源和被交换节点的绑定数据
    QTreeWidgetItem* pSrcItem = GetNodeById(_qstrSrcId);
    if (nullptr == pSrcItem)
    {
        return -1;
    }

    CLS_TreeItem srcData;
    GetBindData(pSrcItem, srcData);

    QTreeWidgetItem* pDesItem = GetNodeById(_qstrDesId);
    if (nullptr == pDesItem)
    {
        return -1;
    }

    CLS_TreeItem desData;
    GetBindData(pDesItem, desData);

    QTreeWidgetItem *pSrcParent = pSrcItem->parent();
    if (nullptr == pSrcParent)
    {
        return -1;
    }

    int iChildCount = pSrcParent ->childCount();
    //原下标位置，如果是最后一个元素，不能再下移
    int iSrcIndex = pSrcParent->indexOfChild(pSrcItem);
    if (iSrcIndex < 0 || iSrcIndex >= iChildCount-1)
    {
        return -1;
    }

    int iDesIndex = pSrcParent->indexOfChild(pDesItem);
    if (iDesIndex < 0 || iDesIndex >= iChildCount)
    {
        return -1;
    }

    //改绑定
    int iExchangeTemp = srcData.m_iSort;
    srcData.m_iSort = desData.m_iSort;
    desData.m_iSort = iExchangeTemp;

    QVariant qvaSrcData;
    qvaSrcData.setValue(srcData);
    pSrcItem->setData(0, Qt::UserRole+1, qvaSrcData);

    QVariant qvaDesData;
    qvaDesData.setValue(desData);
    pDesItem->setData(0, Qt::UserRole+1, qvaDesData);

    //改界面
    QList<QTreeWidgetItem*> qlistChilds;
    for (int i = 0; i < iChildCount; ++i)
    {
        qlistChilds << pSrcParent->child(i);
    }

    pSrcParent->takeChildren();
    qlistChilds[iSrcIndex] = qlistChilds[iDesIndex];
    qlistChilds[iDesIndex] = pSrcItem;
    pSrcParent->addChildren(qlistChilds);
    scrollToItem(pSrcItem);
    setCurrentItem(pSrcItem);
    return 0;
}

